home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_7_3a.arc / DISPLAY.CPP < prev    next >
C/C++ Source or Header  |  1989-02-22  |  5KB  |  255 lines

  1. // display.cpp    the Display class methods
  2. //
  3. // (c) Aspen Scientific 1989. All Rights Reserved.
  4. // Author: Vaughn Vernon
  5.  
  6. #include "display.cls"
  7.  
  8. // for Microsoft C, not Zortech
  9. #ifndef __ZTC__
  10. # include <memory.h>
  11. # include <conio.h>
  12. #else
  13. static void movedata(unsigned, unsigned, unsigned, unsigned, unsigned);
  14. #endif
  15.  
  16. // ***************************************************************
  17. // ** the Display methods in this file are implemented for MS-DOS
  18. // ** in a text display (non-graphics) environment.  it uses
  19. // ** 8086 interrupts and the Microsoft C int86() function, as
  20. // ** well as far pointers to the video memory map segment.
  21. // ***************************************************************
  22.  
  23. #include <dos.h>
  24.  
  25. static union REGS vRegs;
  26. static union REGS videoSaveMode;
  27. static const unsigned monoSeg  = 0xb000;
  28. static const unsigned colorSeg = 0xb800;
  29.  
  30. #if defined(M_I86SM) || defined(M_I86MM)
  31. static unsigned ds;
  32. #endif
  33.  
  34. static unsigned map[80];
  35.  
  36. Display::Display(const Mouse * mou) : cursor(0,0)
  37. {
  38.     if (init == 1)
  39.         return;
  40.  
  41.     mouse = mou;
  42.  
  43.     // for small and medium models (small data), need data seg
  44.     struct SREGS segs;
  45.     segread(&segs);
  46.     ds = segs.ds;
  47.  
  48.     // find out the current video mode, save
  49.     // it, then set the new mode if necessary.
  50.  
  51.     vRegs.h.ah = 0x0f;
  52.     int86(0x10, &vRegs, &vRegs);
  53.     videoSaveMode = vRegs;
  54.  
  55.     // return of 7 in AL register is mono
  56.     if (vRegs.h.al == 7) {
  57.         videoSeg = monoSeg;
  58.         color = 0;
  59.         snow  = 0;
  60.     }
  61.     else {
  62.  
  63.         videoSeg = colorSeg;
  64.         color = 1;
  65.  
  66.         if (vRegs.h.al != 3) {
  67.             vRegs.h.ah = 0;
  68.             vRegs.h.al = 3;
  69.             int86(0x10, &vRegs, &vRegs);
  70.         }
  71.  
  72.         // check for a snowing display; an EGA
  73.         // or VGA is automatic no-snow.
  74.  
  75.         unsigned EGAMemory, EGAMode;
  76.  
  77.         vRegs.h.ah = 0x12;
  78.         vRegs.h.bl = 0x10;
  79.         int86(0x10, &vRegs, &vRegs);
  80.  
  81.         EGAMemory = vRegs.h.bl;
  82.         EGAMode   = vRegs.h.bh;
  83.  
  84.         // if the returned memory is out of range, or
  85.         // the ega/vga card is not attached to the color
  86.         // display (EGAMode != 0), assume snow.
  87.  
  88.         if (EGAMemory < 0 || EGAMemory > 3 || EGAMode != 0)
  89.             snow = 1;
  90.         else
  91.             snow = 0;
  92.     }
  93.  
  94.     // set the Display size
  95.     origin(Point(0,0));
  96.     corner(Point(24,79));
  97.  
  98.     clear();
  99.  
  100.     draw();
  101.  
  102.     init=1;
  103. }
  104.  
  105. Display::~Display()
  106. {
  107.     clear();
  108.     cursor(0,0);
  109.     draw();
  110.     vRegs = videoSaveMode;
  111.     int86(0x10, &vRegs, &vRegs);
  112. }
  113.  
  114. void
  115. Display::clear()
  116. {
  117.     Point size = extent();
  118.  
  119.     mouse->hide();
  120.  
  121.     vRegs.h.dh = size.x() + 1;
  122.     vRegs.h.dl = size.y() + 1;
  123.     vRegs.h.bh = defAttr.get() >> 8;
  124.     vRegs.x.cx = 0;
  125.     vRegs.h.al = 0;
  126.     vRegs.h.ah = 6;
  127.     int86(0x10, &vRegs, &vRegs);
  128.  
  129.     mouse->show();
  130. }
  131.  
  132. void
  133. Display::operator()(unsigned row, unsigned col)
  134. {
  135.     Point top, bot;
  136.  
  137.     top = origin();
  138.     bot = corner();
  139.  
  140.     if (row < top.x() || row > bot.x() ||
  141.         col < top.y() || col > bot.y())
  142.         return;
  143.  
  144.     // move cursor
  145.     cursor(int(row), int(col));
  146.     draw();
  147. }
  148.  
  149. void
  150. Display::cursorOff()
  151. {
  152.     vRegs.x.cx = 0x2000;
  153.     vRegs.h.ah = 1;
  154.     int86(0x10, &vRegs, &vRegs);
  155. }
  156.  
  157. void
  158. Display::cursorOn()
  159. {
  160.     if (hasColor())
  161.         vRegs.x.cx = 0x0607;
  162.     else
  163.         vRegs.x.cx = 0x0b0c;
  164.  
  165.     vRegs.h.ah = 1;
  166.     int86(0x10, &vRegs, &vRegs);
  167. }
  168.  
  169. void
  170. Display::putString(Point & p, const unsigned char * s, DisplayAttr & a)
  171. {
  172.     cursor = p;
  173.  
  174.     register unsigned c = cursor.y();
  175.     register unsigned len=0;
  176.     unsigned *mp = map;
  177.     for ( ; c <= width() && *s; ++c, ++len)
  178.         *mp++ = (unsigned)*s++ | a.get();
  179.  
  180.     mouse->hide();
  181.  
  182.     // protect against flicker
  183.     if (snow)
  184.         while ((inp(0x03da) & 8) == 0)
  185.             ;
  186.  
  187. #if defined(M_I86SM) || defined(M_I86MM)
  188.     movedata(ds, (unsigned)map,
  189. #else
  190.     movedata(FP_SEG(map), FP_OFF(map),
  191. #endif
  192.         videoSeg, cursor.x() * 160 + cursor.y() * 2, len * 2);
  193.  
  194.     mouse->show();
  195.  
  196.     cursor(cursor.x(), c);
  197. }
  198.  
  199. void
  200. Display::putChar(Point & p, unsigned char c, DisplayAttr & a)
  201. {
  202.     cursor = p;
  203.  
  204.     *map = c | a.get();
  205.  
  206.     mouse->hide();
  207.  
  208.     // protect against flicker
  209.     if (snow)
  210.         while ((inp(0x03da) & 8) == 0)
  211.             ;
  212.  
  213. #if defined(M_I86SM) || defined(M_I86MM)
  214.     movedata(ds, (unsigned)map,
  215. #else
  216.     movedata(FP_SEG(map), FP_OFF(map),
  217. #endif
  218.         videoSeg, cursor.x() * 160 + cursor.y() * 2, 2);
  219.  
  220.     mouse->show();
  221.  
  222.     if (cursor.y() != width())
  223.         cursor(cursor.x(), cursor.y() + 1);
  224. }
  225.  
  226. // just update cursor
  227. void
  228. Display::draw()
  229. {
  230.     vRegs.h.dh = cursor.x();
  231.     vRegs.h.dl = cursor.y();
  232.     vRegs.h.bh = 0;
  233.     vRegs.h.ah = 2;
  234.     int86(0x10, &vRegs, &vRegs);
  235. }
  236.  
  237. #ifdef __ZTC__
  238.  
  239. static void
  240. movedata(unsigned sSeg, unsigned sOff, unsigned dSeg, unsigned dOff, unsigned n)
  241. {
  242.     unsigned far *src, far *dest;
  243.  
  244.     src  = MK_FP(sSeg, sOff);
  245.     dest = MK_FP(dSeg, dOff);
  246.  
  247.     // divide by 2
  248.     n >>= 1;
  249.  
  250.     for (register int i=0; i < n; ++i)
  251.         *dest++ = *src++;
  252. }
  253.  
  254. #endif
  255.